package com.mindbook.vip.gawxchatinfo.utils.wx;

import com.alibaba.fastjson.JSONObject;
import com.mindbook.vip.gawxchatinfo.exception.wx.AccessTokenException;
import com.mindbook.vip.gawxchatinfo.utils.RedisUtils;
import com.mindbook.vip.gawxchatinfo.utils.http.HttpRequestUtils;
import com.mindbook.vip.gawxchatinfo.utils.properties.ApplicationContextUtil;
import com.mindbook.vip.gawxchatinfo.utils.result.ResultEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @NAME: wxb
 * @DATE: 2022/4/16
 * @Description 获取微信小程序的access_token的值
 **/
@Component
public class AccessTokenUtils {

    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";

    private static final String ACCESS_TOKEN_NAME_REDIS="access_token";

    @Autowired private HttpRequestUtils httpRequestUtils;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 获取微信小程序的access_token的值
     * ：先从Redis中获取，如果存在，则取出来。如果不存在，则发送请求到微信端获取
     * @return
     */
    public String getAccessToken() {
        Object accessToken = redisUtils.get(ACCESS_TOKEN_NAME_REDIS);
        //如果获取到的accessToken的值为空，则发送请求从微信服务器中获取
        if(accessToken==null){
            return getAccessTokenByHttp();
        }
        //如果redis中已经存在，则直接返回去即可
        return accessToken.toString();
    }

    /**
     * 发送请求从微信服务器上获取access_token
     * @return String access_token
     */
    private String getAccessTokenByHttp(){
        //构建请求的参数
        Map<String, String> map = new LinkedHashMap<>();
        map.put("grant_type", "client_credential");
        map.put("appid", ApplicationContextUtil.getProperty("wx.wxchat.appid"));
        map.put("secret", ApplicationContextUtil.getProperty("wx.wxchat.appsecret"));

        //发送请求
        String result = httpRequestUtils.sendGetRequest(ACCESS_TOKEN_URL, map);
        System.out.println("result:" + result);

        //解析返回来的值
        JSONObject jsonObject = JSONObject.parseObject(result);
        //当正确获取到access_token的值以后，将access_token保存到redis中
        String access_token = jsonObject.getString("access_token");
        if (null != access_token) {
            //将access_token的值保存在Redis中
            redisUtils.set(ACCESS_TOKEN_NAME_REDIS, access_token, Long.parseLong(jsonObject.getString("expires_in")));

            //将access_token的值返回去
            return access_token;
        } else {
            //如果不存在，则根据code的值获取错误信息，并提示相关错误
            String errcode = jsonObject.getString("errcode");
            String errMsg = getErrMsg(errcode);
            throw new AccessTokenException(Integer.parseInt(errcode),errMsg);
        }
    }

    /**
     * 根据code的值获取access_token获取失败的原因
     *
     * @param code
     * @return
     */
    private String getErrMsg(String code) {
        String errMsg = "";
        switch (code) {
            case "-1":
                errMsg = ResultEnum.ACCESS_TOKEN_SYSTEM_BUSY.getMsg();
                break;
            case "40001":
                errMsg = ResultEnum.ACCESS_TOKEN_APP_SECRET_ERROR.getMsg();
                break;
            case "40002":
                errMsg = ResultEnum.ACCESS_TOKEN_GRANT_TYPE_ERROR.getMsg();
                break;
            case "40013":
                errMsg = ResultEnum.ACCESS_TOKEN_APPID_ERROR.getMsg();
                break;
            default:
                errMsg = "获取access_token的错误不在列表内";
        }
        return errMsg;
    }


}
